<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div>
      <form>
        <input name="a" value="3" type="file" />
      </form>
      <h2>宏任务</h2>
      <ol>
        <li>script (可以理解为外层同步代码)</li>
        <li>setTimeout/setInterval</li>
        <li>UI 事件, addEventListener</li>
        <li>postMessage，MessageChannel5. setImmediate，I/O（Node.js）</li>
      </ol>
      <h2>微任务</h2>
      <ol>
        <li>promise.then(cb)</li>
        <li>process.nextTick(cb) // nodejs</li>
        <li>Proxy 监听，vue3 数据变更</li>
        <li>MutationObserver</li>
      </ol>
    </div>
    <script>
      // 1. GET（拿，查）/PUT（放，改）/POST（推，增）/DELETE（删）
      // fetch axios 本质用法一致

      // GET/DELETE 无 body
      fetch("http://122.9.139.38:4000/ping?param=1")
        // 两段 then
        .then((res) => res.text())
        .then((res) => {
          //   console.log(res);
        });

      // 不愿意有这些功能
      axios({
        url:
          "http://122.9.139.38:4000/ping" +
          // 查询参数，一般是 GET/DELETE 请求带上的
          "?param=1&param2=2",
        // params 这属性是固定的
        // params: { param: "1", param2: "2" },
      }).then((res) => {
        // console.log(res.data);
      });

      // PUT/POST 有 body
      fetch("http://122.9.139.38:4000/books", {
        method: "POST",
        headers: {
          "content-type": "application/json",
        },
        body: JSON.stringify({
          author: "test author",
          publisher: "test publisher",
          bookname: "test bookname",
        }),
      })
        .then((res) => {
          //   console.log("fetch 第一段", res);
          //   res.status
          if (res.status !== 200) {
            throw new Error();
          }
          return res.json();
        })
        .then((res) => {
          //   console.log("fetch result", res);
        });

      // config
      axios({
        url: "http://122.9.139.38:4000/books",
        method: "POST",
        data: {
          author: "test author",
          publisher: "test publisher",
          bookname: "test bookname",
        },
      }).then((res) => {
        // 全部内容一段 then 处理
        // console.log("axios result", res);
      });

      // 2. formData 数据结构

      // 对象 初始化，增删查改
      let a = {
        a: 1,
      };
      // 增加
      a.b = 2;
      // 删除
      delete a.a;
      // 查询
      a.b;
      // 修改
      a.b = 3;
      //   console.log(a);
      // 如果用对象，传给后端需要 JSON.stringify

      // formData 初始化 只是一种易于传输的数据结构
      const formData = new FormData(document.querySelector("form"));
      const arr = new Array();
      // 增加
      formData.append("b", 2);
      arr.push(2);
      // 删除
      formData.delete("b");
      arr.splice(0, 1);
      // 查询 a 是不是 form 标签上来的
      formData.get("a");
      arr[0];
      // 修改
      formData.set("a", "12");
      arr[0] = 3;

      // 打印 formData
      formData.forEach((value, key) => {
        // console.log(key, value);
      });
      arr.forEach((val, key) => {
        // console.log(key, val);
      });

      document.querySelector("input").onchange = () => {
        const formData = new FormData(document.querySelector("form"));
        // console.log(formData.get("a")); // 可以拿
        formData.forEach((value, key) => {
          //   console.log(value, key);
        });
        // 你需不需要用 form，考量是你用没有 form 标签
        // 你发给后端的是不是 formData，是后端规定的
      };

      // 3. Promise 基本使用
      // 创建
      function wait() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            // resolved
            resolve();
            // rejected
            reject();
          }, 4000);
        });
      }
      //   console.log(wait());

      // .then
      function wait() {
        return new Promise((resolve) => {
          setTimeout(() => {
            document.body.style.backgroundColor = "red";
            console.log("宏任务打印", 1);
            setTimeout(() => {
              console.log("下一个宏任务，下一个事件循环");
            }, 0);
            // 立即注册一个微任务，在宏任务之后执行
            Promise.resolve().then(() => {
              console.log("hahahah");
            });
            resolve();
            console.log("宏任务打印", 2);
          }, 4000);
        });
      }
      // .then 实在 wait 后面
      // .then 的语义：一段时间以后
      wait().then(() => {
        console.log(3);
      });
      // 类似于 setTimeout 里面的回调，优先级更高
      // 宏任务 batch 一堆事 异步 api 里面

      // .Promise.then() 注意，是.then里面的回调，优先级更低
      // 微任务

      // 微：只做一件事
      // 一段时间以后，干一件事，再过一段时间以后，再干一件事

      // 当前事件循环（宏 -> 微 -> 渲染） -> 下一个事件循环

      // Promise.resolve() 注册在当前事件循环的微任务
      // setTimeout(()=>{},0) 注册在下一侧事件循环的宏任务
    </script>
  </body>
</html>
